﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System.Reflection;

namespace Away.Common.Repository;

public abstract class RepositoryBase<TContext> : IRepository where TContext : DbContext
{
    private readonly TContext _context;
    public RepositoryBase(TContext context)
    {
        _context = context;
    }

    /// <summary>
    /// 追踪数据的修改
    /// <br/> 自动更新时间
    /// </summary>
    private void ChangeTracker()
    {
        var changedEntities = _context.ChangeTracker.Entries()
           .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified)
           .ToList();

        var now = DateTime.Now;
        changedEntities.ForEach(e =>
        {
            var properties = e.Properties.ToList();
            if (e.State == EntityState.Added)
            {
                foreach (var property in properties)
                {
                    switch (property.Metadata.Name)
                    {
                        case "CreateTime":
                            property.CurrentValue = now;
                            break;
                        case "UpdateTime":
                            property.CurrentValue = now;
                            break;
                    }
                }
            }
            else if (e.State == EntityState.Modified)
            {
                foreach (var property in properties)
                {
                    switch (property.Metadata.Name)
                    {
                        case "CreateTime":
                            property.IsModified = false;
                            break;
                        case "UpdateTime":
                            property.CurrentValue = now;
                            break;
                    }
                }
            }
        });
    }

    public int SaveChanges()
    {
        return _context.SaveChanges();
    }

    public Task<int> SaveChangesAsync()
    {
        return _context.SaveChangesAsync();
    }

    public bool Save()
    {
        ChangeTracker();
        return _context.SaveChanges() > 0;
    }

    public async Task<bool> SaveAsync()
    {
        ChangeTracker();
        return (await _context.SaveChangesAsync()) > 0;
    }

    public void Add<TEntity>(params TEntity[] entitys) where TEntity : class
    {
        _context.AddRange(entitys);
    }

    public void Remove<TEntity>(params TEntity[] entitys) where TEntity : class
    {
        _context.RemoveRange(entitys);
    }

    public void Update<TEntity>(params TEntity[] entitys) where TEntity : class
    {
        _context.UpdateRange(entitys);
    }  
    public IQueryable<TEntity> Query<TEntity>() where TEntity : class
    {
        return _context.Set<TEntity>();
    }
}
